iT邦幫忙

2019 iT 邦幫忙鐵人賽

DAY 10
0
自我挑戰組

單元測試開發購物車功能系列 第 10

Day10: 新增 Session 儲存

  • 分享至 

  • xImage
  •  

昨天已經完成了 ArrayStore
今天就將 ArrayStore 改造成 SessionStore
所以要做的第一件事請就是建立 Interface

// src/Store.php

namespace Recca0120\Cart;

interface Store
{
    public function put($item);

    public function remove($item);

    public function items();
}

接下來則是修改 Cart.php 的程式碼

// src/Cart.php

namespace Recca0120\Cart;

class Cart
{
    private $store;

    public function __construct(Store $store = null)
    {
        $this->store = $store ?: new ArrayStore();
    }

    public function put($item)
    {
        $this->store->put($item);

        return $this;
    }

    public function remove($item)
    {
        $this->store->remove($item);
    }

    public function items()
    {
        return $this->store->items();
    }

    public function total()
    {
        return array_sum(array_map(function ($item) {
            return $item['total'];
        }, $this->items()));
    }
}

改完後再執行一次 unitest
確認沒問題後,我們就可以專心的來撰寫 SessionStore

// tests/SessionStoreTest.php

<?php

namespace Recca0120\Cart\Tests;

use Recca0120\Cart\Item;
use PHPUnit\Framework\TestCase;
use Recca0120\Cart\SessionStore;

class SessionStoreTest extends TestCase
{
    /**
     * @test
     * @runInSeparateProcess
     */
    public function 新增商品()
    {
        $item = $this->createItem('商品01', 100, 1);

        $store = new SessionStore();
        $store->put($item);

        $this->assertArraySubset([$item], $store->items());
    }

    /**
     * @test
     * @runInSeparateProcess
     */
    public function 移除商品()
    {
        $store = new SessionStore();
        $store->put($item1 = $this->createItem('商品01', 100, 2));
        $store->put($item2 = $this->createItem('商品02', 200, 1));

        $store->remove($item1);

        $this->assertEquals([$item2], $store->items());
    }

    private function createItem($name, $price, $qty)
    {
        return new Item([
            'name' => $name,
            'price' => $price,
            'quantity' => $qty,
        ]);
    }
}
// src/SessionStore.php

namespace Recca0120\Cart;

class SessionStore implements Store
{
    public function put($item)
    {
        $this->initialize();

        array_push($_SESSION['cart'], $item);

        return $this;
    }

    public function remove($item)
    {
        $this->initialize();

        $_SESSION['cart'] = array_values(array_filter($this->items(), function ($o) use ($item) {
            return $o !== $item;
        }));
    }

    public function items()
    {
        $this->initialize();

        return $_SESSION['cart'];
    }

    private function initialize()
    {
        if (session_status() == PHP_SESSION_NONE) {
            session_start();
        }

        if (isset($_SESSION['cart']) === false) {
            $_SESSION['cart'] = [];
        }
    }
}

接下來只要將 SessionStore 注入到 Cart 裡
這樣就算按 F5 之後,資訊也會保留住了
明天就來瀏覽器實際的執行看看


上一篇
Day09: 增加存檔機制
下一篇
Day11: 使用 Mockery 重構 Cart 測試
系列文
單元測試開發購物車功能12
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言